package org.solovyev.android.calculator.wizard;

import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.release.ChooseThemeReleaseNoteFragment;
import org.solovyev.android.calculator.release.ChooseThemeReleaseNoteStep;
import org.solovyev.android.calculator.release.ReleaseNoteFragment;
import org.solovyev.android.calculator.release.ReleaseNoteStep;
import org.solovyev.android.wizard.Wizard;
import org.solovyev.android.wizard.WizardFlow;
import org.solovyev.android.wizard.WizardStep;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public abstract class WizardFragment extends Fragment implements View.OnClickListener {

	@Nullable
	protected TextView nextButton;

	@Nullable
	protected TextView prevButton;

	private WizardStep step;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		step = findStepByClassName();
	}

	@Nonnull
	private WizardStep findStepByClassName() {
		if (this instanceof ReleaseNoteFragment) {
			return new ReleaseNoteStep(getArguments());
		}

		if(this instanceof ChooseThemeReleaseNoteFragment) {
			return new ChooseThemeReleaseNoteStep(getArguments());
		}

		for (CalculatorWizardStep step : CalculatorWizardStep.values()) {
			if (step.getFragmentClass().equals(getClass())) {
				return step;
			}
		}

		throw new AssertionError("Wizard step for class " + getClass() + " was not found");
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		final View view = inflater.inflate(R.layout.fragment_wizard, container, false);

		final ViewGroup content = (ViewGroup) view.findViewById(R.id.wizard_content);
		inflater.inflate(getViewResId(), content, true);

		nextButton = (TextView) view.findViewById(R.id.wizard_next);
		if (nextButton != null) {
			nextButton.setOnClickListener(this);
		}
		prevButton = (TextView) view.findViewById(R.id.wizard_prev);
		if (prevButton != null) {
			prevButton.setOnClickListener(this);
		}

		final Wizard wizard = getWizardActivity().getWizard();
		final WizardFlow flow = wizard.getFlow();
		final boolean canGoNext = flow.getNextStep(step) != null;
		final boolean canGoPrev = flow.getPrevStep(step) != null;
		final boolean firstTimeWizard = TextUtils.equals(wizard.getName(), CalculatorWizards.FIRST_TIME_WIZARD);
		if (canGoNext) {
			if (canGoPrev || !firstTimeWizard) {
				setupNextButton(R.string.cpp_wizard_next);
			} else {
				setupNextButton(R.string.cpp_wizard_start);
			}
		} else {
			setupNextButton(R.string.cpp_wizard_finish);
		}

		if (canGoPrev) {
			setupPrevButton(R.string.cpp_wizard_back);
		} else {
			if (firstTimeWizard) {
				setupPrevButton(R.string.cpp_wizard_skip);
			}
		}

		return view;
	}

	protected final void setupNextButton(int textResId) {
		assert nextButton != null;
		nextButton.setText(textResId);
		nextButton.setVisibility(View.VISIBLE);
	}

	protected final void setupPrevButton(int textResId) {
		assert prevButton != null;
		prevButton.setText(textResId);
		prevButton.setVisibility(View.VISIBLE);
	}

	@LayoutRes
	protected abstract int getViewResId();

	@Override
	public void onClick(View v) {
		final int id = v.getId();
		final WizardActivity activity = getWizardActivity();
		if (id == R.id.wizard_next) {
			if (activity.canGoNext()) {
				activity.goNext();
			} else {
				activity.finishWizard();
			}
		} else if (id == R.id.wizard_prev) {
			if (activity.canGoPrev()) {
				activity.goPrev();
			} else {
				activity.finishWizardAbruptly();
			}
		}
	}

	private WizardActivity getWizardActivity() {
		return (WizardActivity) getActivity();
	}

	public WizardStep getStep() {
		if (step == null) {
			step = findStepByClassName();
		}
		return step;
	}

	public void onNext() {
		getStep().onNext(this);
	}

	public void onPrev() {
		getStep().onPrev(this);
	}
}
